import {
  Controller,
  Post,
  Body,
  HttpCode,
  HttpStatus,
  Get,
  Param,
  Delete,
  Res,
  Sse,
} from '@nestjs/common';
import { Response } from 'express';
import { ChatService } from './chat.service';
import { ChatRequestDto, ChatResponseDto } from './dto/chat.dto';
import { ChatSessionService } from './chat-session.service';
import { Observable } from 'rxjs';
import { map } from 'rxjs/operators';

@Controller('api')
export class ChatController {
  constructor(
    private readonly chatService: ChatService,
    private readonly chatSessionService: ChatSessionService,
  ) {}

  @Post('chat')
  @HttpCode(HttpStatus.OK)
  async chat(@Body() request: ChatRequestDto): Promise<ChatResponseDto> {
    return this.chatService.chat(request);
  }

  @Post('chat/stream')
  async chatStream(@Body() request: ChatRequestDto, @Res() res: Response) {
    res.setHeader('Content-Type', 'text/event-stream');
    res.setHeader('Cache-Control', 'no-cache');
    res.setHeader('Connection', 'keep-alive');
    res.setHeader('X-Accel-Buffering', 'no');

    let isCompleted = false;
    const subscription = this.chatService.chatStream(request).subscribe({
      next: (data) => {
        try {
          res.write(`data: ${data}\n\n`);
        } catch (writeError) {
          console.error('Error writing to response:', writeError);
        }
      },
      error: (error) => {
        console.error('Stream error:', error);
        if (!isCompleted) {
          try {
            res.write(`data: ${JSON.stringify({ error: error.message })}\n\n`);
            res.end();
          } catch (endError) {
            console.error('Error ending response:', endError);
          }
          isCompleted = true;
        }
      },
      complete: () => {
        if (!isCompleted) {
          try {
            res.end();
            isCompleted = true;
          } catch (endError) {
            console.error('Error ending response:', endError);
          }
        }
      },
    });

    res.on('close', () => {
      console.log('Client disconnected from stream');
      if (!isCompleted) {
        subscription.unsubscribe();
        isCompleted = true;
      }
    });
  }

  @Get('sessions')
  async getSessions() {
    const sessions = await this.chatSessionService.findAll();
    return sessions.map((session) => ({
      id: session._id.toString(),
      title: session.title,
      model: session.model,
      messageCount: session.messages.length,
      createdAt: session.createdAt,
      updatedAt: session.updatedAt,
    }));
  }

  @Get('sessions/:id')
  async getSession(@Param('id') id: string) {
    const session = await this.chatSessionService.findById(id);
    if (!session) {
      return null;
    }
    return {
      id: session._id.toString(),
      title: session.title,
      model: session.model,
      messages: session.messages.map((msg) => ({
        role: msg.role,
        content: msg.content,
        timestamp: msg.timestamp,
      })),
      createdAt: session.createdAt,
      updatedAt: session.updatedAt,
    };
  }

  @Delete('sessions/:id')
  async deleteSession(@Param('id') id: string) {
    const result = await this.chatSessionService.delete(id);
    return { success: result };
  }

  @Post('sessions')
  async createSession(@Body() body: { title?: string; model: string }) {
    const session = await this.chatSessionService.create({
      title: body.title || '新对话',
      model: body.model,
      messages: [],
    });
    return {
      id: session._id.toString(),
      title: session.title,
      model: session.model,
      messageCount: 0,
      createdAt: session.createdAt,
      updatedAt: session.updatedAt,
    };
  }
}

